/**
 * Created by jinxs on 14-6-24.
 * 依赖：
 * ui.core.js
 * ui.button.js
 * ui.buttonbar.js
 * ui.draggable.js
 * ui.resizable.js
 * ui.mask.js
 * ui.loading.js
 * ui.position.js
 */
(function ($) {
    /**
     * 缓存名称
     * @type {string}
     * @private
     */
    var _cacheName = 'uiPanel';
    var loadingID = 'palLoading';
    /**
     * @class 面板
     * @requires {@link uiButton}
     * @constructor uiPanel
     * @summary 构造函数
     * @param [options] {Object|String} 组件配置参数|要调用的组件方法名
     * @param [param] {Object} 表示要调用的组件方法的参数
     * @example
     * // 构件组件
     * $('#divMenu').uiPanel({width: 160, height: 500});
     * // 调用组件方法{@link options}
     * $('#divMenu').uiPanel("options");
     */
    $.fn.uiPanel = function (options, param) {
        if (typeof options == 'string') {
            return $.fn.uiPanel.methods[options](this, param);
        }
        return this.each(function () {
            var me = $(this);
            var cache = me.data(_cacheName);

            options = options || {};
            if (cache) {
                $.extend(cache.options, options);
            } else {
                me.data(_cacheName, {
                    options: $.extend({}, $.fn.uiPanel.defaults, $.fn.parseUIConfig(me, null), options)
                });
            }
            _init(me);
        });
    };
    /**
     * 方法
     * @lends uiPanel.prototype
     */
    $.fn.uiPanel.methods = {
        /**
         * @summary 获得组件的数据
         * @name uiPanel#data
         * @param target
         * @returns {*|Function|HTMLOptionsCollection|options|options}
         */
        data: function (target) {
            return $.data(target[0], _cacheName);
        },
        /**
         * @summary 获得组件的面板对象
         * @name uiPanel#options
         * @param target
         * @returns {*|Function|HTMLOptionsCollection|options|options}
         */
        options: function (target) {
            return target.data(_cacheName).options;
        },
        /**
         * @summary 获得组件的面板对象
         * @name uiPanel#panel
         * @function
         * @returns {jQuery} 组件的面板对象的内容
         */
        panel: function (target) {
            return target;
        },
        /**
         * @summary 获得组件的标题对象
         * @name uiPanel#header
         * @function
         * @returns {jQuery} 组件的面板对象的内容
         */
        header: function (target) {
            return $.getByParentID(target.getElemID(), $.uiTemplate.panel.header);
        },
        /**
         * @summary 设置组件的图标
         * @name uiPanel#icon
         * @function
         * @returns {jQuery} 组件的面板对象的内容
         */
        icon: function (target) {
            return $.getByParentID(target.getElemID(), $.uiTemplate.panel.icon);
        },
        /**
         * @summary 获得组件的标题文本
         * @name uiPanel#title
         * @function
         * @returns {jQuery} 组件的面板对象的内容
         */
        title: function (target) {
            return $.getByParentID(target.getElemID(), $.uiTemplate.panel.title);
        },
        /**
         * @summary 获得组件的工具栏
         * @name uiPanel#toolbar
         * @function
         * @returns {jQuery} 组件的面板对象的内容
         */
        toolbar: function (target) {
            return $.getByParentID(target.getElemID(), $.uiTemplate.panel.toolbar);
        },
        /**
         * @summary 获得组件的内容
         * @name uiPanel#content
         * @function
         * @returns {jQuery} 组件的面板对象的内容
         */
        content: function (target) {
            return $.getByParentID(target.getElemID(), $.uiTemplate.panel.content);
        },
        /**
         * @summary 获得组件的按钮栏
         * @name uiPanel#buttonbar
         * @function
         * @returns {jQuery} 组件的面板对象的内容
         */
        buttonbar: function (target) {
            return $.getByParentID(target.getElemID(), $.uiTemplate.panel.buttonbar);
        },
        /**
         * @summary 设置组件是否显示内容区边框
         * @name uiPanel#border
         * @param show {boolean}是否显示边框
         * @function
         * @returns {Object} 组件的面板对象
         */
        border: function (target, show, borderWidth) {
            _contentBorder(target, show, borderWidth);
            return target;
        },
        /**
         * @summary 刷新组件
         * @name uiPanel#refresh
         * @param url {String} 地址
         * @function
         * @returns {Object} 组件的面板对象
         */
        refresh: function (target, url) {
            if (url) {
                $.data(target[0], _cacheName).options.url = url;
            }
            _renderContent(target, true);
            return target;
        },
        /**
         * @summary 折叠组件
         * @name uiPanel#collapse
         * @param target
         * @param animate {boolean}是否有动画
         * @returns {Object} 组件的面板对象
         */
        collapse: function (target, animate) {
            _collapsed(target, animate);
            return target;
        },
        /**
         * @summary 展开组件
         * @name uiPanel#collapse
         * @param target
         * @param animate {boolean}是否有动画
         * @returns {Object} 组件的面板对象
         */
        expand: function (target, animate) {
            _expand(target, animate);
            return target;
        },
        /**
         * @summary 调整组件的大小
         * @name uiPanel#resize
         * @param target
         * @param position {String} 位置
         * @returns {Object} 组件的面板对象
         */
        resize: function (target, position) {
            var opts = $.data(target[0], _cacheName).options;
            if (position != undefined) {
                if (position.left != undefined) {
                    opts.left = position.left;
                }
                if (position.top != undefined) {
                    opts.top = position.top;
                }
                if (position.width != undefined) {
                    opts.width = position.width;
                }
                if (position.height != undefined) {
                    opts.height = position.height;
                }
                if (position.zIndex != undefined) {
                    opts.zIndex = position.zIndex;
                }
            }
            _resize(target);
            return target;
        },
        /**
         * @summary 打开组件
         * @name uiPanel#open
         * @param target
         * @param forceOpen {boolean}是否强制打开
         * @returns {Object} 组件的面板对象
         */
        open: function (target, forceOpen) {
            _open(target, forceOpen);
            return target;
        },
        /**
         * @summary 关闭组件
         * @name uiPanel#close
         * @param target
         * @param forceClose {Boolean}是否强制关闭
         * @returns {Object} 组件的面板对象
         */
        close: function (target, forceClose) {
            _close(target, forceClose);
            return target;
        },
        /**
         * @summary 移除组件
         * @name uiPanel#destroy
         * @param target
         * @param forceDestroy {Boolean} 在'forceDestroy'参数设置为true的时候，销毁面板时将跳过'onBeforeDestory'回调函数。
         * @returns {Object} 组件的面板对象
         */
        destroy: function (target, forceDestroy) {
            _destory(target, forceDestroy);
            return target;
        }
    };
    /**
     * 默认配置
     * @lends uiPanel.prototype
     */
    $.fn.uiPanel.defaults = {
        /**
         * @type String
         * @default ""
         * @summary 设置组件的ID
         */
        id: '',
        /**
         * @type Boolean
         * @default false
         * @summary true时，页面需要引用animate.css
         */
        animate:true,
        /**
         * @type String
         * @default ""
         * @summary 打开时的动画样式名称
         */
        animateOpen:'fadeIn',
        /**
         * @type String
         * @default ""
         * @summary 关闭时的动画样式名称
         */
        animateClose:'fadeOut',
        /**
         * @type Boolean
         * @default true
         * @summary true时，panel只能在父容器边框内，false时，panel可以超出父容器边框
         */
        inContainer: true,
        /**
         * 样式枚举：<br/><br/>
         * <TABLE cellSpacing="1" width="100%" class="params">
         * <TR>
         * <TH width="12%">名称</TH>
         * <TH width="88%">说明</TH></TR>
         * <TR><TD align=center>ui_panel_primary</TD><TD>主样式</TD></TR>
         * <TR><TD align=center>ui_panel_success</TD><TD>成功样式</TD></TR>
         * <TR><TD align=center>ui_panel_info</TD><TD>信息样式</TD></TR>
         * <TR><TD align=center>ui_panel_warning</TD><TD>警告样式</TD></TR>
         * <TR><TD align=center>ui_panel_danger</TD><TD>危险样式</TD></TR>
         * </TABLE>
         * @type String
         * @default ""
         * @summary 设置组件的风格
         */
        panelStyle: '',
        /**
         * @type Boolean
         * @default false
         * @summary 设置组件是否自动填充
         */
        autoFit: false,
        /**
         * @type String
         * @default ""
         * @summary 指示组件图标
         */
        icon: '',
        /**
         * 属性说明：<br/><br/>
         * <TABLE cellSpacing="1" width="100%" class="params">
         * <TR>
         * <TH width="12%">属性</TH>
         * <TH width="88%">说明</TH></TR>
         * <TR><TD align=center>icon</TD><TD>图标样式</TD></TR>
         * <TR><TD align=center>color</TD><TD>颜色</TD></TR>
         * <TR><TD align=center>size</TD><TD>大小（像素）</TD></TR>
         * </TABLE>
         * @type Object
         * @default null
         * @summary 使用奥森字体图标，示例{ icon:'fa-comments-o',color:'#FF0000',size:20}
         */
        fontIcon: null,
        /**
         * @type Object
         * @default null
         * @summary 指示组件的上边距(支持Number、百分比)
         */
        top: null,
        /**
         * @type Object
         * @default null
         * @summary 指示组件的左边距(支持Number、百分比)
         */
        left: null,
        /**
         * @type String
         * @default ""
         * @summary 指示组件标题
         */
        title: '',
        showTitle: true,
        /**
         * @type Boolean
         * @default false
         * @summary 是否初始化组件的框架内容
         */
        iniframe: false,
        /**
         * 可选值有get, post
         * @type String
         * @default "post"
         * @summary 向指定的url请求数据时使用的方法
         */
        method: 'get',
        /**
         * @type String
         * @default ""
         * @summary 指定远程数据加载的url
         */
        url: '',
        /**
         * @type Boolean
         * @default true
         * @summary 指示组件在加载远程数据时是否显示加载进度条
         */
        showLoading: true,
        /**
         * @type Boolean
         * @default false
         * @summary 请求框架内容时是否设置随机参数
         */
        urlRandomParam: false,
        /**
         * @type Boolean
         * @default false
         * @summary 设置组件是否打开时刷新
         */
        updateOnOpen: false,
        /**
         * @type Boolean
         * @default false
         * @summary 设置组件是否延时加载
         */
        lazyLoad: false,
        /**
         * @type Boolean
         * @default true
         * @summary 设置组件是否只有首次时加载
         */
        firstLoad: true,
        /**
         * @type Object
         * @default {}
         * @summary 指示组件的请求参数
         */
        queryParams: {},
        /**
         * @type String
         * @default ""
         * @summary 指示组件的内容
         */
        content: '',
        /**
         * @type Boolean
         * @default true
         * @summary 设置组件是否显示边框
         */
        border: true,
        /**
         * @type Number
         * @default 1
         * @summary 设置组件边框宽度，仅border为ture时有效
         */
        borderWidth: 1,
        /**
         * @type String
         * @default 0px
         * @summary 设置组件内边距
         */
        padding: '0px',
        /**
         * @type Object
         * @default 0
         * @summary 指示组件的最小宽度(支持Number、百分比)
         */
        minWidth: 0,
        /**
         * @type Object
         * @default 0
         * @summary 指示组件的最小高度(支持Number、百分比)
         */
        minHeight: 0,
        /**
         * @type Object
         * @default 0
         * @summary 指示组件的宽度(支持Number、百分比)
         */
        width: 0,
        /**
         * @type Object
         * @default 0
         * @summary 指示组件的高度(支持Number、百分比)
         */
        height: 0,
        /**
         * @type Boolean
         * @default true
         * @summary 指示组件是否显示标题栏
         */
        showHeader: true,
        /**
         * @type Boolean
         * @default false
         * @summary 指示组件是否显示按钮栏
         */
        showBtnBar: false,
        /**
         * @type Array
         * @default []
         * @summary 设置组件的buttons值
         */
        buttons: [],
        /**
         * 可选值：left,right,center
         * @type String
         * @default "center"
         * @summary 组件按钮栏的对齐方式
         */
        btnBarDir: 'center',
        /**
         * @type Boolean
         * @default false
         * @summary 指示组件是否可拖拽
         */
        draggable: false,
        /**
         * @type Boolean
         * @default false
         * @summary 指示组件是否可调整大小
         */
        resizable: false,
        /**
         * @type Boolean
         * @default false
         * @summary 指示组件是否可关闭
         */
        closable: false,
        /**
         * @type Boolean
         * @default false
         * @summary 指示组件是否默认关闭
         */
        closed: false,
        /**
         * @type Boolean
         * @default false
         * @summary 指示组件是否可最大化
         */
        maximizable: false,
        /**
         * @type Boolean
         * @default false
         * @summary 指示组件是否默认最大化
         */
        maximized: false,
        /**
         * @type Array
         * @default [15,15,15,15]
         * @summary 组件最大化时与父容器的间距(上、左、下、右)
         */
        maxPadding: [0, 0, 0, 0],
        /**
         * @type Boolean
         * @default false
         * @summary 指示组件是否可折叠
         */
        collapsible: false,
        /**
         * @type Boolean
         * @default false
         * @summary 指示组件是否默认折叠
         */
        collapsed: false,
        /**
         * @type object
         * @default null
         * @summary 指示组件拖拽的对象
         */
        dragHandle: null,
        /**
         * @type Number
         * @default 0
         * @summary 指示组件的zIndex
         */
        zIndex: 0,
        /**
         * @event
         * @name uiPanel#onBeforeCollapse
         * @type function
         * @default function () { }
         * @summary 设置组件折叠之前的事件
         */
        onBeforeCollapse: function () {
        },
        /**
         * @event
         * @name uiPanel#onCollapse
         * @type function
         * @default function () { }
         * @summary 设置组件折叠时的事件
         */
        onCollapse: function () {
        },
        /**
         * @event
         * @name uiPanel#onBeforeExpand
         * @type function
         * @default function () { }
         * @summary 设置组件展开之前的事件
         */
        onBeforeExpand: function () {
        },
        /**
         * @event
         * @name uiPanel#onExpand
         * @type function
         * @default function () { }
         * @summary 设置组件展开时的事件
         */
        onExpand: function () {
        },
        /**
         * @event
         * @name uiPanel#onBeforeOpen
         * @type function
         * @default function () { }
         * @summary 设置组件打开之前的事件
         */
        onBeforeOpen: function () {
        },
        /**
         * @event
         * @name uiPanel#onOpen
         * @type function
         * @default function () { }
         * @summary 设置组件打开时的事件
         */
        onOpen: function () {
        },
        /**
         * @event
         * @name uiPanel#onBeforeClose
         * @type function
         * @default function () { }
         * @summary 设置组件关闭之前的事件
         */
        onBeforeClose: function () {
        },
        /**
         * @event
         * @name uiPanel#onClose
         * @type function
         * @default function () { }
         * @summary 设置组件关闭时的事件
         */
        onClose: function () {
        },
        /**
         * @event
         * @name uiPanel#onBeforeDestroy
         * @type function
         * @default function () { }
         * @summary 设置组件移除之前的事件
         */
        onBeforeDestroy: function () {
        },
        /**
         * @event
         * @name uiPanel#onDestroy
         * @type function
         * @default function () { }
         * @summary 设置组件移除时的事件
         */
        onDestroy: function () {
        },
        /**
         * @event
         * @name uiPanel#onBeforeLoad
         * @type function
         * @default function () { }
         * @summary 设置组件加载之前的事件
         */
        onBeforeLoad: function () {
        },
        /**
         * 若函数返回false，将不执行默认的错误处理
         * @event
         * @name uiPanel#onLoadError
         * @type function
         * @default function () { }
         * @summary 设置组件加载失败的事件，参数参见$.ajax.error
         */
        onLoadError: function () {
        },
        /**
         * @event
         * @name uiPanel#onLoadComplete
         * @type function
         * @default function () { }
         * @summary 设置组件加载完成的事件
         */
        onLoadComplete: function () {
        },
        /**
         * @event
         * @name uiPanel#onPanelResize
         * @type function
         * @default function () { }
         * @summary 组件改变大小时触发
         */
        onPanelResize: function () {
        }
    };
    //////--------------------------------内部方法------------------------------
    /**
     * 创建按钮
     * @param target 目标对象
     */
    var _init = function (target) {
        var options = target.data(_cacheName).options;
        var targetID;
        if (options.id != '') {
            target[0].id = options.id;
            targetID = options.id;
        } else {
            target.setElemID();
            targetID = target.getElemID();
            options.id = targetID;
        }

        var header, content, toolbar;
        if (target.find('.ui_panel_content').length == 0) {
            var contentHtml = target.children().detach();
            target.addClass('ui_panel');
            var reg = new RegExp('({palID})', 'g');
            target.append($.uiTemplate.panel.html.replace(reg, targetID));
            content = $.getByParentID(targetID, $.uiTemplate.panel.content);
            content.append(contentHtml);
        } else {
            header = target.find('.ui_panel_header').setIDByParentID(targetID, $.uiTemplate.panel.header);
            header.find('.ui_panel_icon').setIDByParentID(targetID, $.uiTemplate.panel.icon);
            header.find('.ui_panel_title').setIDByParentID(targetID, $.uiTemplate.panel.title);
            target.find('.ui_panel_content').setIDByParentID(targetID, $.uiTemplate.panel.content);
            target.find('.ui_panel_buttonbar').setIDByParentID(targetID, $.uiTemplate.panel.buttonbar);
            toolbar = target.find('.ui_panel_toolbar').setIDByParentID(targetID, $.uiTemplate.panel.toolbar);
            toolbar.find('.ui_panel_toolbar_close').setIDByParentID(targetID, $.uiTemplate.panel.btnClose);
            toolbar.find('.ui_panel_toolbar_max').setIDByParentID(targetID, $.uiTemplate.panel.btnMax);
        }
        if (options.panelStyle != '') {
            target.addClass(options.panelStyle);
        }
        if (options.zIndex > 0) {
            target.css('zIndex', options.zIndex);
        }
        _renderBtnBar(target);//兼容考虑
        if (options.closed == true) {
            _close(target, true, true);
        } else {
            _open(target);
        }

        return target;
    };
    var _renderHeader = function (target) {
        var options = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();
        var header = $.getByParentID(targetID, $.uiTemplate.panel.header);
        var icon = $.getByParentID(targetID, $.uiTemplate.panel.icon);
        var title = $.getByParentID(targetID, $.uiTemplate.panel.title);
        if (!options.showHeader) {
            header.remove();
        }
        else {
            icon.removeClass();
            if (options.fontIcon && !_IEunder6) {
                options.fontIcon.size = options.fontIcon.size || 16;
                options.fontIcon.color = options.fontIcon.color || 'inherit';
                icon.addClass('ui_panel_fontIcon fa').addClass(options.fontIcon.icon)
                    .css({color: options.fontIcon.color, fontSize: options.fontIcon.size});
            } else {
                if (options.icon) {
                    if (options.icon.indexOf('.') > 0) {
                        icon.addClass('icon ui_panel_icon').html("<img src='" + options.icon + "'>");
                    } else {
                        icon.addClass('icon ui_panel_icon ' + $.uiTemplate.iconStyle_Pre + options.icon);
                    }
                } else {
                    icon.hide();
                }
            }
            if (options.showTitle) {
                if (options.title) {
                    title.html(options.title);
                } else {
                    title.hide();
                }
            } else {
                title.remove();
            }
        }
    };
    var _renderBtnBar = function (target) {
        var options = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();
        var btnbar = $.getByParentID(targetID, $.uiTemplate.panel.buttonbar);
        if (btnbar.length > 0 && options.showBtnBar) {
            var buttons = options.buttons;
            if (buttons.length > 0) {
                for (var i = 0; i < buttons.length; i++) {
                    var btnOpts = buttons[i];
                    var btn = $('<button class="button"></button>').appendTo(btnbar);
                    btn.uiButton(btnOpts);
                }
            }
            btnbar.uiButtonBar({direction: options.btnBarDir, height: 28, buttonBorder: true});
        } else {
            btnbar.remove();
        }
    };
    var _renderContent = function (target, refresh) {
        refresh = refresh === undefined ? false : refresh;
        var options = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();
        var content = $.getByParentID(targetID, $.uiTemplate.panel.content);
        if (options.padding != '') {
            content.css('padding', options.padding);
        }
        options.onBeforeLoad.call(target);
        if (!refresh && $.trim(content.html()) != "") {
            content.addClass('overflowAuto');
        } else {
            if (options.url != '') {
                if (refresh) {
                    _loadContent(target);
                }
            } else {
                content.addClass('overflowAuto');
                if (options.content) {
                    content.append(options.content);
                }
                options.onLoadComplete.call(target);
                options.onOpen.call(target);
            }
        }
    };
    var _loadContent = function (target) {
        var options = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();
        var excludeId = '#' + targetID;
        var content = $.getByParentID(targetID, $.uiTemplate.panel.content);
        var tempHref = options.url;

        if (options.urlRandomParam) {
            tempHref = $.urlAddRandom(options.url);
        }
        if (options.iniframe) {
            content.removeClass('overflowAuto');
            var ifrm = $.getByParentID(targetID, 'iframe');
            var params = $.param(options.queryParams);

            if (params) {
                tempHref += /\?/.test(tempHref) ? '&' : '?' + params;
            }
            if (options.showLoading) {
                $.uiLoading.show({container: target, loadingID: loadingID, excludeSelector: excludeId});
            }
            if (ifrm.length > 0) {
                ifrm[0].src = tempHref;
            } else {
                var iframeID = $.getIDByParentID(targetID, 'iframe');
                ifrm = $('<iframe id="' + iframeID + '" src="' + tempHref + '" class="ui_panel_iframe" frameborder="0" scrolling="auto"></iframe>');
                ifrm.load(function () {
                    options.onLoadComplete.call(target);
                    options.onOpen.call(target);
                    if (options.showLoading) {
                        $.uiLoading.hide({container: target, loadingID: loadingID, excludeSelector: excludeId});
                    }
                }).appendTo(content);
            }
        }
        else {
            content.addClass('overflowAuto');
            $.ajax({
                type: options.method,
                url: tempHref,
                cache: true,
                showLoading: false,
                data: options.queryParams,
                dataType: "html",
                success: function (data) {
                    content.empty();
                    content.append(data);
                    return false;
                },
                complete: function () {
                    options.onLoadComplete.call(target);
                    options.onOpen.call(target);
                },
                error: function (xhr) {
                    if (options.onLoadError.apply(target, arguments) !== false) {
                        content.append(xhr.responseText);
                    }
                    return false;
                }
            });
        }
    };
    var _resizable = function (target) {
        var options = $.data(target[0], _cacheName).options;
        if (options.resizable) {
            var targetID = target.getElemID();
            var btnbar = $.getByParentID(targetID, $.uiTemplate.panel.buttonbar);
            var content = $.getByParentID(targetID, $.uiTemplate.panel.content);
            var header = $.getByParentID(targetID, $.uiTemplate.panel.header);
            var resizeHand = $('<div class="icon icon_draghandler"></div>').setIDByParentID(targetID, $.uiTemplate.panel.resizeHand).appendTo(target)
                .css({zIndex: parseInt(target.css("zIndex")) + 1, position: 'absolute', right: 0, bottom: 0});
            target.resizable({
                minWidth: $.parseWH('minWidth', options.minWidth, target.parent()),
                minHeight: $.parseWH('minHeight', options.minHeight, target.parent()),
                onStartResize: function () {
                    target.addClass('ui_panel_proxy');
                    content.height(0);
                },
                onResize: function () {
                },
                onStopResize: function (e) {
                    target.removeClass('ui_panel_proxy');
                    var pos = target.position();
                    options.top = pos.top;
                    options.left = pos.left;
                    options.width = target.width();
                    options.height = target.height();
                    if (options.inContainer) {
                        var d = e.data;
                        var tar = $(d.target);
                        var par = $(d.parent);
                        if (d.left + tar.outerWidth() > par.width()) {
                            options.width = par.width() - d.left;
                        }
                        if (d.top + tar.outerHeight() > par.height()) {
                            options.height = par.height() - d.top;
                        }
                    }
                    _resize(target);
                    return false;
                }
            });
        }
    };
    var _draggable = function (target) {
        var options = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();
        var header = $.getByParentID(targetID, $.uiTemplate.panel.header);
        var title = $.getByParentID(targetID, $.uiTemplate.panel.title);
        if (options.draggable) {
            if (!options.dragHandle) {
                if (options.showHeader) {
                    options.dragHandle = title;
                }
            }
            target.draggable({
                handle: options.dragHandle,
                proxy: function (source) {
                    var p = $('<div class="ui_panel_proxy" style="width:' + target.width() + 'px;height:' + target.height() + 'px;z-index:9999999;"></div>');
                    p.appendTo('body');
                    return p;
                },
                onStartDrag: function () {
                    target.hide();
                },
                onStopDrag: function (e) {
                    if (options.inContainer) {
                        var d = e.data;
                        if (d.left < 0) {
                            d.left = 0
                        }
                        if (d.top < 0) {
                            d.top = 0
                        }
                        if (d.left + $(d.target).outerWidth() > $(d.parent).width()) {
                            d.left = $(d.parent).width() - $(d.target).outerWidth();
                        }
                        if (d.top + $(d.target).outerHeight() > $(d.parent).height()) {
                            d.top = $(d.parent).height() - $(d.target).outerHeight();
                        }
                        target.css({
                            left: d.left,
                            top: d.top
                        });
                    }
                    options.top = parseInt(target.css("top"));
                    options.left = parseInt(target.css("left"));
                    target.show();
                }
            });
        }
    };
    var _maximizable = function (target) {
        var options = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();
        var btnMax = $.getByParentID(targetID, $.uiTemplate.panel.btnMax);
        var toolbar = $.getByParentID(targetID, $.uiTemplate.panel.toolbar);
        var header = $.getByParentID(targetID, $.uiTemplate.panel.header);
        if (options.maximizable) {
            if (btnMax.length > 0) {
                btnMax.show();
            } else {
                btnMax = $('<a type="button" class="ui_panel_toolbar_btn ui_panel_toolbar_max">' +
                    '<span id="' + $.getIDByParentID(targetID, $.uiTemplate.panel.btnMax_Icon) + '" class="icon icon_pal_max"></span></a>')
                    .setIDByParentID(targetID, $.uiTemplate.panel.btnMax).appendTo(toolbar);
            }
            btnMax.unbind("click.panel").bind("click.panel", function (e) {
                if (options.maximized) {
                    options.maximized = false;
                    _isMax(target, false);
                }
                else {
                    options.maximized = true;
                    _isMax(target, true);
                }
                _resize(target);
                e.stopPropagation();
            });
            header.unbind("dblclick").bind("dblclick", function (e) {
                btnMax.click();
                e.stopPropagation();
            });
        }
        else {
            if (btnMax.length > 0) {
                btnMax.hide();
            }
        }
    };
    var _isMax = function (target, isMax) {
        var options = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();
        if (options.maximizable) {
            var btnMax_icon = $.getByParentID(targetID, $.uiTemplate.panel.btnMax_Icon);
            var resizeHand = $.getByParentID(targetID, $.uiTemplate.panel.resizeHand);
            if (isMax) {
                btnMax_icon.removeClass('icon_pal_max').addClass('icon_pal_min');
                if (options.draggable) {
                    target.draggable("disable");
                }
                if (options.resizable) {
                    target.resizable("disable");
                    resizeHand.hide();
                }
            }
            else {
                btnMax_icon.removeClass('icon_pal_min').addClass('icon_pal_max');
                if (options.draggable) {
                    target.draggable("enable");
                }
                if (options.resizable) {
                    target.resizable("disable");
                    target.resizable("enable");
                    resizeHand.show();
                }
            }
        }
    };
    var _closeable = function (target) {
        var options = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();
        var btnClose = $.getByParentID(targetID, $.uiTemplate.panel.btnClose);
        var toolbar = $.getByParentID(targetID, $.uiTemplate.panel.toolbar);
        if (options.closable) {
            if (btnClose.length > 0) {
                btnClose.show();
            } else {
                btnClose = $('<a type="button" class="ui_panel_toolbar_btn ui_panel_toolbar_close">' +
                    '<span class="icon icon_close"></span></a>')
                    .setIDByParentID(targetID, $.uiTemplate.panel.btnClose).appendTo(toolbar);
            }
            btnClose.unbind("click").bind("click", function (e) {
                _close(target);
                e.stopPropagation();
            });
        }
        else {
            if (btnClose.length > 0) {
                btnClose.hide();
            }
        }
    };
    var _collapsible = function (target) {
        var options = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();
        var btnColl = $.getByParentID(targetID, $.uiTemplate.panel.btnColl);
        var toolbar = $.getByParentID(targetID, $.uiTemplate.panel.toolbar);
        var header = $.getByParentID(targetID, $.uiTemplate.panel.header);
        if (options.collapsible) {
            if (btnColl.length > 0) {
                btnColl.show();
            } else {
                var iconClass = 'icon_pal_col';
                var iconTitle = '收缩';
                if (options.collapsed) {
                    iconClass = 'icon_pal_exp';
                    iconTitle = '展开';
                }
                btnColl = $('<a type="button" class="ui_panel_toolbar_btn ui_panel_toolbar_col" title="' + iconTitle + '">' +
                    '<span id="' + $.getIDByParentID(targetID, $.uiTemplate.panel.btnColl_Icon) + '" class="icon ' + iconClass + '"></span></a>')
                    .setIDByParentID(targetID, $.uiTemplate.panel.btnColl).appendTo(toolbar);
            }
            var btnColl_icon = $.getByParentID(targetID, $.uiTemplate.panel.btnColl_Icon);
            btnColl.unbind("click.panel").bind("click.panel", function (e) {
                if (options.collapsed) {
                    btnColl_icon.removeClass('icon_pal_exp').addClass('icon_pal_col').attr('title', '收缩');
                    _expand(target, false);
                }
                else {
                    btnColl_icon.removeClass('icon_pal_col').addClass('icon_pal_exp').attr('title', '展开');
                    _collapsed(target, false);
                }
                e.stopPropagation();
            });
            header.unbind("click").bind("click", function (e) {
                btnColl.click();
                // 这会阻止layout 上下的click事件使Panel不能展开
                //e.stopPropagation();
            });
        }
        else {
            if (btnColl.length > 0) {
                btnColl.remove();
            }
        }
    };
    var _resize = function (target) {
        var targetID = target.getElemID();
        var header = $.getByParentID(targetID, $.uiTemplate.panel.header);
        var icon = $.getByParentID(targetID, $.uiTemplate.panel.icon);
        var title = $.getByParentID(targetID, $.uiTemplate.panel.title);
        var content = $.getByParentID(targetID, $.uiTemplate.panel.content);
        var btnbar = $.getByParentID(targetID, $.uiTemplate.panel.buttonbar);
        var toolbar = $.getByParentID(targetID, $.uiTemplate.panel.toolbar);
        var options = $.data(target[0], _cacheName).options;
        _contentBorder(target, options.border, options.borderWidth);

        var parent = target.parent();
        if (options.maximized) {
            var pos = {left: 0, top: 0};
            pos.left = parent.scrollLeft();
            pos.top = parent.scrollTop();
            target.outerWidth(parent.width() - options.maxPadding[1] - options.maxPadding[3]);
            target.outerHeight(parent.height() - options.maxPadding[0] - options.maxPadding[2]);
            target.css('top', options.maxPadding[0] + pos.top);
            target.css('left', options.maxPadding[1] + pos.left);
        } else {
            if (options.top) {
                target.css('top', options.top);
            }
            if (options.left) {
                target.css('left', options.left);
            }
            if (options.autoFit) {
                target.autoFit(true, false);
            } else {
                target.autoFit(false);
                options.width = $.parseWH("width", options.width, parent);
                options.minWidth = $.parseWH("minWidth", options.minWidth, parent);
                options.height = $.parseWH("height", options.height, parent);
                options.minHeight = $.parseWH("minHeight", options.minHeight, parent);
                var width = Math.max(Math.max(options.width, 0), options.minWidth || 0);
                var height = Math.max(Math.max(options.height, 0), options.minHeight || 0);
                target.outerWidth(width);
                if (!options.collapsed) {
                    target.outerHeight(height);
                }
            }
        }
        var contentH = target.height();
        if (header.length > 0) {
            contentH -= header.outerHeight();
        }
        if (btnbar.length > 0 && options.showBtnBar) {
            contentH -= btnbar.outerHeight();
        }
        content.outerHeight(contentH);
        content.outerWidth(target.width());
        _contentChildrenResize(content);
        options.onPanelResize.call(target);
    };
    var _open = function (target, forceOpen) {
        var options = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();
        var content = $.getByParentID(targetID, $.uiTemplate.panel.content);
        if (forceOpen != true) {
            if (options.onBeforeOpen.call(target) == false) {
                return;
            }
        }
        options.closed = false;
        target.show();
        target.attr('closed', false);
        content.attr('closed', false);
        if (options.firstLoad) {
            _renderHeader(target);
            _draggable(target);
            _resizable(target);
            _maximizable(target);
            _closeable(target);
            _collapsible(target);
            if (options.maximized) {
                _resize(target);
                _isMax(target, true);
            } else {
                _resize(target);
            }
            _renderContent(target, true);

            if (options.collapsed) {
                var btnColl_icon = $.getByParentID(targetID, $.uiTemplate.panel.btnColl_Icon);
                options.collapsed = false;
                btnColl_icon.removeClass('icon_pal_col').addClass('icon_pal_exp').attr('title', '展开');
                _collapsed(target, false);
            }

            target.bind("_resize", function () {
                if (target.attr('closed') !== 'true' && options.maximized) {
                    _resize(target);
                }
            });
            options.firstLoad = false;
        }
        else {
            target.width(options.tempWidth).height(options.tempHeight);
            if (options.url != '' && options.updateOnOpen) {
                _loadContent(target);
            } else {
                options.onOpen.call(target);
            }
        }
        if(options.animate){
            target.removeClass('animated '+options.animateClose).addClass('animated '+options.animateOpen+' fast');
        }

    };
    var _close = function (target, forceClose, firstLoad) {
        var options = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();

        if(options.closed){
            return;
        }
        var content = $.getByParentID(targetID, $.uiTemplate.panel.content);
        if (forceClose != true) {
            if (options.onBeforeClose.call(target) == false) {
                return;
            }
        }
        target.attr('closed', true);
        content.attr('closed', true);
        if (firstLoad) {
            target.hide();
            return target;
        }
        options.closed = true;
        var height=target.height();
        if(height>0) {
            options.tempWidth = target.width();
            options.tempHeight = target.height();
        }
        if(options.animate){
            target.removeClass('animated '+options.animateOpen).addClass('animated '+options.animateClose+' fast');
            setTimeout(function(){
                target.width(0).height(0);
                options.onClose.call(target);
            },500);
        }else {
            target.width(0).height(0);
            options.onClose.call(target);
        }
        return target;
    };
    var _destory = function (target, forceDestroy) {
        var options = $.data(target[0], _cacheName).options;
        if (forceDestroy != true) {
            if (options.onBeforeDestroy.call(target) == false) {
                return;
            }
        }
        var content = target.uiPanel($.uiTemplate.panel.content);
        content.destroyIframe();
        target.remove();
        options.onDestroy.call(target);
    };
    var _contentBorder = function (target, showBorder, borderWidth) {
        if (showBorder) {
            target.css('borderWidth', borderWidth);
        } else {
            target.css('borderWidth', 0);
        }
    };
    var _collapsed = function (target, animate) {
        var options = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();
        var header = $.getByParentID(targetID, $.uiTemplate.panel.header);
        var content = $.getByParentID(targetID, $.uiTemplate.panel.content);
        if (options.collapsed == true) {
            return;
        }
        content.stop(true, true);
        if (options.onBeforeCollapse.call(target) == false) {
            return;
        }
        if (animate == true) {
            target.animate({height: header.outerHeight()}, 'fast', function () {
                _collControl(target, options, true);
                options.onCollapse.call(target);
            });
        } else {
            target.outerHeight(header.outerHeight());
            _collControl(target, options, true);
            options.onCollapse.call(target);
        }
    };
    var _expand = function (target, animate) {
        var options = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();
        var content = $.getByParentID(targetID, $.uiTemplate.panel.content);
        if (options.collapsed == false) {
            return;
        }
        content.stop(true, true);
        if (options.onBeforeExpand.call(target) == false) {
            return;
        }
        if (animate == true) {
            target.animate({height: options.height}, 'fast', function () {
                options.collapsed = false;
                options.onExpand.call(target);
            });
        } else {
            target.outerHeight(options.height);
            _collControl(target, options, false);
            options.onExpand.call(target);
        }
    };
    var _collControl = function (target, options, coll) {
        var targetID = target.getElemID();
        var content = $.getByParentID(targetID, $.uiTemplate.panel.content);
        var btnbar = $.getByParentID(targetID, $.uiTemplate.panel.buttonbar);
        var resizeHand = $.getByParentID(targetID, $.uiTemplate.panel.resizeHand);
        var objs = content.find('OBJECT,IFRAME').length;
        if (coll) {
            btnbar.hide();
            resizeHand.hide();
            if (objs == 0) {
                content.hide();
            } else {
                content.width(0).height(0);
            }
            content.attr('closed', true);
            options.collapsed = true;
        } else {
            btnbar.show();
            resizeHand.show();
            if (objs == 0) {
                content.show();
            }
            content.attr('closed', false);
            content.autoFit(true, false);
            options.collapsed = false;
            _contentChildrenResize(content);
        }
    };
    var _contentChildrenResize = function (content) {
        content.children().each(function () {
            var elem = $(this);
            elem.triggerHandler('_resize');
        });
    }
})(jQuery);

